package edu.mercer.sse.ldap;

import java.security.GeneralSecurityException;
import java.sql.SQLException;
import java.util.Map;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldif.LDIFException;

import edu.mercer.sse.errors.CriticalException;
import edu.mercer.sse.errors.CustomLogger;
import edu.mercer.sse.errors.ErrorLoggingVisitor;
import edu.mercer.sse.errors.LoggerCustom;
import edu.mercer.sse.annotations.Fulfills;
import edu.mercer.sse.app.Config;

/**
 * 
 * Add entry to LDAP.<p>
 * 
 * Input: <b>Database entry</b>. <u>Do not</u> provide existing LDAP entries 
 * 	to this Function.<p>
 * 
 * For use with corresponding Predicate showing entries requiring addition.<p>
 *  
 * @see LDAPAddPredicate
 * 
 * @see Function
 */

public class LDAPAddFunction implements Function<Map<String, String>, Boolean>
{
	private static final CustomLogger _log = LoggerCustom.obtainLog( 
			
			"LDAPAddFunction", 
				
			Config.getLogLevel());	
	
	/**
	 * Add entry to LDAP.<p>
	 * 
	 * No-arg constructor.<p>
	 * 
	 * Input: <b>Database entry</b>. <u>Do not</u> provide existing LDAP 
	 * 	entries to this Function.<p>
	 * 
	 * For use with corresponding Predicate showing entries requiring 
	 * 	addition.<p>
	 * 
	 * @see LDAPAddPredicate
	 * 
	 * @see Function
	 */
	
	public LDAPAddFunction(){}

	
	@Override
	public Boolean apply( final Map<String, String> dbEntry )
	{
		Boolean result = false;
		
		try
		{
			if( LDAPUtility.isPresent( ImmutableMap.copyOf( dbEntry) ) )
			{
				_log.warning( "entry already in ldap, not added: " 
						+ dbEntry );
				
				return false;
			
			}//if
	
			result = LDAPUtility.writeEntry( LDAPUtility.convertDBEntryToLDAP( 
					dbEntry ));
			
			if( result && ! LDAPUtility.isPresent( ImmutableMap.copyOf( 
					dbEntry)))
			{
				_log.warning( "entry could not be located in ldap following "
						+ "successful writeEntry method usage: " 
						+ dbEntry );
				
				return false;
				
			}//if

			if( result ) result = LDAPGroupUniqNames.addMember( LDAPUtility
					.findDN( dbEntry ));
			
		}
		catch( final LDAPException			   | 
					  GeneralSecurityException | 
					  SQLException 			   | 
					  LDIFException err )
		{
			final CriticalException errWrapped = new CriticalException( err );
			errWrapped.accept( new ErrorLoggingVisitor() );

			result = false;
			
		}//try
		
		return result;
		
	}//method

	
	@Fulfills("Object")
	@Override
	public String toString()
	{
		return "Add";
		
	}//method	

	
}//class
